home *** CD-ROM | disk | FTP | other *** search
-
- /**********************************************
- *
- * file d:\cips\ed.c
- *
- * Functions: This file contains
- * erosion
- * dilation
- * mask_erosion
- * mask_dilation
- * interior_outline
- * exterior_outline
- * copy_3_x_3
- * opening
- * closing
- * get_shape_options
- *
- * Purpose:
- * These functions perform the erosion,
- * dilation, outlining, opening and
- * closing operations.
- *
- * External Calls:
- * wtiff.c - round_off_image_size
- * create_file_if_needed
- * write_array_into_tiff_image
- * tiff.c - read_tiff_header
- * rtiff.c - read_tiff_image
- * numcvrt.c - get_integer
- *
- * Modifications:
- * 14 March 1993 - created
- *
- ************************************************/
-
- #include "cips.h"
-
-
-
- short edmask1[3][3] = {{0, 1, 0},
- {0, 1, 0},
- {0, 1, 0}};
-
- short edmask2[3][3] = {{0, 0, 0},
- {1, 1, 1},
- {0, 0, 0}};
-
- short edmask3[3][3] = {{0, 1, 0},
- {1, 1, 1},
- {0, 1, 0}};
-
- short edmask4[3][3] = {{1, 1, 1},
- {1, 1, 1},
- {1, 1, 1}};
-
-
-
-
-
-
- /*******************************************
- *
- * mask_dilation(...
- *
- * This function performs the dilation
- * operation using the erosion-dilation
- * 3x3 masks given above. It works on
- * 0-value images.
- *
- *******************************************/
-
- mask_dilation(in_name, out_name, the_image, out_image,
- il, ie, ll, le, value, mask_type)
- char in_name[], out_name[];
- int il, ie, ll, le;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- mask_type, value;
- {
- int a, b, count, i, j, k;
- short mask[3][3], max;
-
- /**************************************
- *
- * Copy the 3x3 erosion-dilation mask
- * specified by the mask_type.
- *
- ***************************************/
-
- switch(mask_type){
- case 1:
- copy_3_x_3(mask, edmask1);
- break;
- case 2:
- copy_3_x_3(mask, edmask2);
- break;
- case 3:
- copy_3_x_3(mask, edmask3);
- break;
- case 4:
- copy_3_x_3(mask, edmask4);
- break;
- default:
- printf("\nInvalid mask type, using mask 4");
- copy_3_x_3(mask, edmask4);
- break;
- }
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- /***************************
- *
- * Loop over image array
- *
- ****************************/
-
- printf("\n");
-
- for(i=1; i<ROWS-1; i++){
- if( (i%10) == 0) printf("%3d", i);
- for(j=1; j<COLS-1; j++){
- max = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(mask[a+1][b+1] == 1){
- if(the_image[i+a][j+b] > max)
- max = the_image[i+a][j+b];
- } /* ends if mask == 1 */
- } /* ends loop over b */
- } /* ends loop over a */
- out_image[i][j] = max;
- } /* ends loop over j */
- } /* ends loop over i */
-
- fix_edges(out_image, 3);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends mask_dilation */
-
-
-
-
-
- /*******************************************
- *
- * mask_erosion(...
- *
- * This function performs the erosion
- * operation using the erosion-dilation
- * 3x3 masks given above. It works on
- * 0-value images.
- *
- *******************************************/
-
- mask_erosion(in_name, out_name, the_image, out_image,
- il, ie, ll, le, value, mask_type)
- char in_name[], out_name[];
- int il, ie, ll, le;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- mask_type, value;
- {
- int a, b, count, i, j, k;
- short mask[3][3], min;
-
- /**************************************
- *
- * Copy the 3x3 erosion-dilation mask
- * specified by the mask_type.
- *
- ***************************************/
-
- switch(mask_type){
- case 1:
- copy_3_x_3(mask, edmask1);
- break;
- case 2:
- copy_3_x_3(mask, edmask2);
- break;
- case 3:
- copy_3_x_3(mask, edmask3);
- break;
- case 4:
- copy_3_x_3(mask, edmask4);
- break;
- default:
- printf("\nInvalid mask type, using mask 4");
- copy_3_x_3(mask, edmask4);
- break;
- }
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- /***************************
- *
- * Loop over image array
- *
- ****************************/
-
- printf("\n");
-
- for(i=1; i<ROWS-1; i++){
- if( (i%10) == 0) printf("%3d", i);
- for(j=1; j<COLS-1; j++){
- min = value;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(mask[a+1][b+1] == 1){
- if(the_image[i+a][j+b] < min)
- min = the_image[i+a][j+b];
- } /* ends if mask == 1 */
- } /* ends loop over b */
- } /* ends loop over a */
- out_image[i][j] = min;
- } /* ends loop over j */
- } /* ends loop over i */
-
- fix_edges(out_image, 3);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends mask_erosion */
-
-
-
-
-
- /*******************************************
- *
- * erosion(...
- *
- * This function performs the erosion
- * operation. If a value pixel has more
- * than the threshold number of 0
- * neighbors, you erode it by setting it
- * to 0.
- *
- *******************************************/
-
- erosion(in_name, out_name, the_image, out_image,
- il, ie, ll, le, value, threshold)
- char in_name[], out_name[];
- int il, ie, ll, le;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- threshold, value;
- {
- int a, b, count, i, j, k;
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- /***************************
- *
- * Loop over image array
- *
- ****************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- out_image[i][j] = the_image[i][j];
-
- printf("\n");
-
- for(i=1; i<ROWS-1; i++){
- if( (i%10) == 0) printf("%3d", i);
- for(j=1; j<COLS-1; j++){
- if(the_image[i][j] == value){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b] == 0)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold) out_image[i][j] = 0;
- } /* ends if the_image == value */
- } /* ends loop over j */
- } /* ends loop over i */
-
- fix_edges(out_image, 3);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends erosion */
-
-
-
-
-
- /*******************************************
- *
- * dilation(...
- *
- * This function performs the dilation
- * operation. If a 0 pixel has more than
- * threshold number of value neighbors,
- * you dilate it by setting it to value.
- *
- *******************************************/
-
- dilation(in_name, out_name, the_image, out_image,
- il, ie, ll, le, value, threshold)
- char in_name[], out_name[];
- int il, ie, ll, le;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- threshold, value;
- {
- int a, b, count, i, j, k;
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- /***************************
- *
- * Loop over image array
- *
- ****************************/
-
- printf("\n");
-
- for(i=1; i<ROWS-1; i++){
- if( (i%10) == 0) printf("%3d", i);
- for(j=1; j<COLS-1; j++){
- out_image[i][j] = the_image[i][j];
- if(the_image[i][j] == 0){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(a!=0 && b!=0){
- if(the_image[i+a][j+b] == value)
- count++;
- } /* ends avoid the center pixel */
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold)
- out_image[i][j] = value;
- } /* ends if the_image == 0 */
- } /* ends loop over j */
- } /* ends loop over i */
-
- fix_edges(out_image, 3);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends dilation */
-
-
-
-
-
- /*******************************************
- *
- * interior_outline(...
- *
- * This function produces the outline of
- * any "holes" inside an object. The
- * method is:
- * output = erosion of input
- * final output = input - output
- *
- *******************************************/
-
- interior_outline(in_name, out_name, the_image,
- out_image, il, ie, ll, le, value,
- mask_type)
- char in_name[], out_name[];
- int il, ie, ll, le;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- mask_type, value;
- {
- int a, b, count, i, j, k;
- short mask[3][3], max;
-
- /**************************************
- *
- * Copy the 3x3 erosion-dilation mask
- * specified by the mask_type.
- *
- ***************************************/
-
- switch(mask_type){
- case 1:
- copy_3_x_3(mask, edmask1);
- break;
- case 2:
- copy_3_x_3(mask, edmask2);
- break;
- case 3:
- copy_3_x_3(mask, edmask3);
- break;
- case 4:
- copy_3_x_3(mask, edmask4);
- break;
- default:
- printf("\nInvalid mask type, using mask 4");
- copy_3_x_3(mask, edmask4);
- break;
- }
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- mask_erosion(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, mask_type);
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] =
- the_image[i][j] - out_image[i][j];
-
- write_array_into_tiff_image(out_name, the_image,
- il, ie, ll, le);
-
- } /* ends interior_outline */
-
-
-
-
-
- /*******************************************
- *
- * exterior_outline(...
- *
- * This function produces the outline of
- * exterior of an object. The
- * method is:
- * output = dilation of input
- * final output = output - input
- *
- *******************************************/
-
-
- exterior_outline(in_name, out_name, the_image, out_image,
- il, ie, ll, le, value, mask_type)
- char in_name[], out_name[];
- int il, ie, ll, le;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- mask_type, value;
- {
- int a, b, count, i, j, k;
- short mask[3][3], max;
-
- /**************************************
- *
- * Copy the 3x3 erosion-dilation mask
- * specified by the mask_type.
- *
- ***************************************/
-
- switch(mask_type){
- case 1:
- copy_3_x_3(mask, edmask1);
- break;
- case 2:
- copy_3_x_3(mask, edmask2);
- break;
- case 3:
- copy_3_x_3(mask, edmask3);
- break;
- case 4:
- copy_3_x_3(mask, edmask4);
- break;
- default:
- printf("\nInvalid mask type, using mask 4");
- copy_3_x_3(mask, edmask4);
- break;
- }
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- mask_dilation(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, mask_type);
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] =
- out_image[i][j] - the_image[i][j];
-
- write_array_into_tiff_image(out_name, the_image,
- il, ie, ll, le);
-
- } /* ends exterior_outline */
-
-
- /***********************************************
- *
- * copy_3_x_3(a, b)
- *
- * This function copies a 3x3 array of shorts
- * from one array to another. It copies array
- * b into array a.
- *
- ***********************************************/
-
- copy_3_x_3(a, b)
- short a[3][3], b[3][3];
- {
- int i, j;
- for(i=0; i<3; i++)
- for(j=0; j<3; j++)
- a[i][j] = b[i][j];
- } /* ends copy_3_x_3 */
-
-
-
-
-
- /*******************************************
- *
- * opening(...
- *
- * Opening is erosion followed by dilation.
- * This routine will use the mask erosion
- * and dilation. You could use the other
- * types and you could mix the two types.
- *
- * The number parameter specifies how
- * erosions to perform before doing one
- * dilation.
- *
- *******************************************/
-
- opening(in_name, out_name, the_image, out_image,
- il, ie, ll, le, value, mask_type, number)
- char in_name[], out_name[];
- int il, ie, ll, le, number;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- mask_type, value;
- {
- int a, b, count, i, j, k;
- short mask[3][3], max;
-
- /**************************************
- *
- * Copy the 3x3 erosion-dilation mask
- * specified by the mask_type.
- *
- ***************************************/
-
- switch(mask_type){
- case 1:
- copy_3_x_3(mask, edmask1);
- break;
- case 2:
- copy_3_x_3(mask, edmask2);
- break;
- case 3:
- copy_3_x_3(mask, edmask3);
- break;
- case 4:
- copy_3_x_3(mask, edmask4);
- break;
- default:
- printf("\nInvalid mask type, using mask 4");
- copy_3_x_3(mask, edmask4);
- break;
- }
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- mask_erosion(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, mask_type);
-
- if(number > 1){
- count = 1;
- while(count < number){
- count++;
- mask_erosion(out_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, mask_type);
- } /* ends while */
- } /* ends if number > 1 */
-
- mask_dilation(out_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, mask_type);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends opening */
-
-
-
-
-
- /*******************************************
- *
- * closing(...
- *
- * Closing is dilation followed by erosion.
- * This routine will use the mask erosion
- * and dilation. You could use the other
- * types and you could mix the two types.
- *
- * The number parameter specifies how
- * dilations to perform before doing one
- * erosion.
- *
- *******************************************/
-
- closing(in_name, out_name, the_image, out_image,
- il, ie, ll, le, value, mask_type, number)
- char in_name[], out_name[];
- int il, ie, ll, le, number;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- mask_type, value;
- {
- int a, b, count, i, j, k;
- short mask[3][3], max;
-
- /**************************************
- *
- * Copy the 3x3 erosion-dilation mask
- * specified by the mask_type.
- *
- ***************************************/
-
- switch(mask_type){
- case 1:
- copy_3_x_3(mask, edmask1);
- break;
- case 2:
- copy_3_x_3(mask, edmask2);
- break;
- case 3:
- copy_3_x_3(mask, edmask3);
- break;
- case 4:
- copy_3_x_3(mask, edmask4);
- break;
- default:
- printf("\nInvalid mask type, using mask 4");
- copy_3_x_3(mask, edmask4);
- break;
- }
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- mask_dilation(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, mask_type);
-
- if(number > 1){
- count = 1;
- while(count < number){
- count++;
- mask_dilation(out_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, mask_type);
- } /* ends while */
- } /* ends if number > 1 */
-
- mask_erosion(out_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, mask_type);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends closing */
-
-
-
-
-
- /*******************************************
- *
- * get_shape_options(...
- *
- * This function interacts with the user
- * to obtain the parameters for calling
- * the shape routines.
- *
- *******************************************/
-
- get_shape_options(type, value, threshold, number)
- char type[];
- int *number, *threshold;
- short *value;
- {
- int not_finished = 1, response;
-
- while(not_finished){
-
- printf("\nThe shape options are:");
- printf("\n\t1. Type is %s", type);
- printf("\n\t recall: EROsion DILation Mask-ERosion"
- "\n\t Mask_DIlation INTerior-outline"
- "\n\t EXTerior-outline THInning"
- "\n\t Dilate-Not-Join OPEning"
- "\n\t CLOsing SPecial-Opening"
- "\n\t SPecial-Closing"
- "\n\t Euclidean-Distance-Measure"
- "\n\t Medial-Axis-Transform");
- printf("\n\t2. value is %d", *value);
- printf("\n\t3. threshold or mask type is %d",
- *threshold);
- printf("\n\t4. number of iterations is %d", *number);
- printf("\n\t (used only in opening and closing)");
- printf("\n\nEnter choice (0 = no change) _\b");
-
- get_integer(&response);
-
- if(response == 0){
- not_finished = 0;
- }
-
- if(response == 1){
- printf("\nEnter type of operation");
- printf("\n\t recall: EROsion DILation Mask-ERosion"
- "\n\t Mask_DIlation INTerior-outline"
- "\n\t EXTerior-outline THInning"
- "\n\t Dilate-Not-Join OPEning"
- "\n\t CLOsing SPecial-Opening"
- "\n\t SPecial-Closing"
- "\n\t Euclidean-Distance-Measure"
- "\n\t Medial-Axis-Transform");
- printf("\n\t:");
- gets(type);
- }
-
- if(response == 2){
- printf("\nEnter value: ___\b\b\b");
- get_integer(value);
- }
-
- if(response == 3){
- printf("\nEnter threshold or mask type: ___");
- printf("\b\b\b");
- get_integer(threshold);
- }
-
- if(response == 4){
- printf("\nEnter number of iterations: ___");
- printf("\b\b\b");
- get_integer(number);
- }
-
- } /* ends while not_finished */
-
- } /* ends get_shape_options */
-